package com.ztgame.modules.sound
{
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.net.URLRequest;
	import flash.utils.Dictionary;
	
	import org.allencuilib.console.Logger;
	
	public class SoundMangager
	{
		public static const SOUND_BG_PVE:String = "BGM_normal.mp3";
		public static const SOUND_BG_PVP:String = "BGM_PVP.mp3";
		public static const SOUND_LEVEL_SUCCESS:String = "victory.mp3";
		public static const SOUND_LEVEL_FAILUE:String = "APC_moving.mp3";
		public static const SOUND_NEW_MESSAGE:String = "new_mail.mp3";
		public static const SOUND_ALERT:String = "alert_2.mp3";
		public static const SOUND_NEW_MISSION:String = "new_mission.mp3";
		private static const REPEAT_COUNT:int = 9999999;
		public static const SOUND_WINDOW_POPUP:String = "window_popup.mp3";
		public static const SOUND_CLICK:String = "click.mp3";
		
		private var soundDict:Dictionary;
		private var _mute:Boolean;
		private var _isEffectMusicOn:Boolean;
		private var _isBackgroundMusicOn:Boolean;
		
		private static var _instance:SoundMangager;
		
		public static function get instance():SoundMangager
		{
			if(!_instance)
			{
				_instance = new SoundMangager();
			}
			
			return _instance;
		}
		
		public function SoundMangager()
		{
			mute = false;
			isEffectMusicOn = true;
			isBackgroundMusicOn = true;
			soundDict = new Dictionary();
		}
		
		public function getSound(name:String):PlayableSoundObject
		{
			return soundDict[name];
		}
		
		public function loadSound(name:String):Sound
		{
			var s:Sound = new Sound();
			s.load(new URLRequest("assets/sound/" + name));
			s.addEventListener(IOErrorEvent.IO_ERROR, onIOError);			
				
			var ps:PlayableSoundObject = new PlayableSoundObject();
			ps.setSound(s);
			ps.mName = name;
			soundDict[name] = ps;
			
			return s;
		}
		
		private function onIOError(e:IOErrorEvent):void
		{
			Logger.Warning(this, "can not load sound "+ (e.target as Sound).url);
		}
		
		//multi 对于一手音乐能否同时播放多个实例
		public function playSound(name:String, type:int=1, volume:Number=1, 
								  startTime:Number=0, loops:int=1, multi:Boolean=false):PlayableSoundObject
		{
			if(!name)
			{
				return null;
			}
			
			var ps:PlayableSoundObject = getSound(name);
			if(!ps)
			{
				loadSound(name);
			}
			
			ps = getSound(name);
			if(!ps)
			{
				return null;
			}			
			
			ps.mType = type;
			ps.mVolume = volume;
			ps.mLoops = loops;
			ps.mName = name;
			if(multi)
				ps.play(startTime, loops);
			else
				ps.playSingle(startTime, loops);
			
			return ps;
		}
		
		public function stopSound(name:String) : void
		{
			var ps:PlayableSoundObject = this.soundDict[name];
			if (ps == null)
			{
				return;
			}			
			ps.stop();
		}
		
		public function stopAllSound():void
		{
			for each(var ps:PlayableSoundObject in soundDict)
			{
				ps.stop();
			}
		}
		
		public function pauseSound(name:String) : void
		{
			var ps:PlayableSoundObject = this.soundDict[name];
			if (ps == null)
			{
				return;
			}
			ps.pause();
		}
		
		public function pauseAllSound():void
		{
			for each(var ps:PlayableSoundObject in soundDict)
			{
				ps.pause();
			}
		}
		
		public function goOn(name:String):void
		{
			var ps:PlayableSoundObject = this.soundDict[name];
			if (ps == null)
			{
				return;
			}			
			ps.goOn();
		}
		
		public function removeSound(name:String):void
		{
			delete soundDict[name];
		}
		
		public function removeAllSound():void
		{
			soundDict =  new Dictionary();
		}
		
		public function get mute():Boolean
		{
			return _mute;
		}
		
		public function set mute(value:Boolean):void
		{
			if(_mute == value)
			{
				return;
			}
			
			_mute = value;
			
			if(_mute)
			{
				stopAllSound();
			}
			else
			{
				if(_isBackgroundMusicOn)
				{
					backgroundMusic.goOn();
				}
				else
				{
					backgroundMusic.pause();
				}
			}
		}
		
		private var backgroundMusic:PlayableSoundObject;
		
		public function playBackgroundMusic(name:String):void
		{
			if(!mute && isBackgroundMusicOn)
			{
				if(backgroundMusic)
				{
					backgroundMusic.stop();
				}
				
				backgroundMusic = playSound(name, PlayableSoundObject.SOUNT_TYPE_BG,0.4,0,REPEAT_COUNT);
			}
		}
		
		public function playEffectMusic(name:String, isLoop:Boolean=false):PlayableSoundObject
		{
			if(!mute && isEffectMusicOn)
			{
				var loops:int = isLoop ? REPEAT_COUNT : 1;
				return playSound(name, PlayableSoundObject.SOUNT_TYPE_EFFECT,1,0,loops,true);
			}
			
			return null;
		}
		
		public function get isEffectMusicOn():Boolean
		{
			return _isEffectMusicOn;
		}
		
		public function set isEffectMusicOn(value:Boolean):void
		{
			if(_isEffectMusicOn == value)
			{
				return;
			}
			
			_isEffectMusicOn = value;
			
			if(!_isEffectMusicOn)
			{
				for each(var ps:PlayableSoundObject in soundDict)
				{
					if(ps.mType == PlayableSoundObject.SOUNT_TYPE_EFFECT)
					{						
						ps.stop();
					}
				}
			}
		}
		
		public function get isBackgroundMusicOn():Boolean
		{
			return _isBackgroundMusicOn;
		}
		
		public function set isBackgroundMusicOn(value:Boolean):void
		{
			if(_isBackgroundMusicOn == value)
			{
				return;
			}
			
			_isBackgroundMusicOn = value;
			
			if(!backgroundMusic)
			{
				return;
			}
			
			if(_isBackgroundMusicOn)
			{
				backgroundMusic.playSingle(0, REPEAT_COUNT);
			}
			else
			{
				backgroundMusic.stop();
			}
		}
		
	}
}